package com.xcc.netty.socket.groupchat;


import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @author frosty
 * @description
 * @date 2019-12-31 31:16:03
 */


public class GroupChatServer {
    //定义熟悉
    private Selector selector;

    private ServerSocketChannel listenChannel;
    private static final int PORT = 8761;


    //初始化
    public GroupChatServer() {
        try {
            //得到选择起
            selector = Selector.open();
            //ServerSocketChannel
            listenChannel = ServerSocketChannel.open();
            //绑定端口
            listenChannel.socket().bind(new InetSocketAddress(PORT));
            //设置非阻塞模式
            listenChannel.configureBlocking(false);
            //将listenChannel 注册到selecter 并绑定事件
            listenChannel.register(selector, SelectionKey.OP_ACCEPT);

        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    /**
     * 监听
     */
    public void listen() {


        while (true) {

            try {
                int count = selector.select();
                if (count == 0) {
                    System.out.println("等待两秒  继续监听");
                    continue;
                }
                if(count>0){
                     Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                     while (iterator.hasNext()){
                          SelectionKey key = iterator.next();
                          if(key.isAcceptable()){
                               SocketChannel sc = listenChannel.accept();
                               sc.configureBlocking(false); //设置非阻塞
                              //注册
                              sc.register(selector,SelectionKey.OP_READ);
                              //提示  上线
                              System.out.println(sc.getRemoteAddress()+"上线了");
                          }

                         //通道发生read事件
                          if(key.isReadable()){
                               //处理读
                              readData(key);
                          }

                           //手动移除
                          iterator.remove();

                     }

                }


            } catch (Exception e) {
                e.printStackTrace();
            }finally {

            }

        }
    }


    //读取客户端消息
    public  void readData(SelectionKey selectionKey)   {
        //定义一个socketChannel
        SocketChannel sc=null;
            try {
                sc=(SocketChannel) selectionKey.channel();
                ByteBuffer buffer=ByteBuffer.allocate(1024);
                 int read = sc.read(buffer);
                   if(read>0){
                        byte[] array = buffer.array();
                       String str = new String(array);
                       System.out.println(("from client:"+str).trim());
                          //向其他客户端 发送消息 专门写一个方法处理
                       sendToOther(str,sc,selector);
                   }

            }catch (Exception e){
                  try {
                      System.out.println(sc.getRemoteAddress()+"离线了");
                      //取消注册
                      selectionKey.cancel();
                      //关闭通道
                      sc.close();
                  }catch (IOException e2){
                      e2.printStackTrace();
                  }
            }

    }

    //转发消息给其他客户端

    public  void sendToOther(String msg,SocketChannel self,Selector selector) throws  IOException{
        System.out.println("服务器转发消息");
       //所有注册到selecor 的channel
         Set<SelectionKey> selectionKeys = selector.keys();

        for (SelectionKey key:  selectionKeys) {
             SocketChannel target = (SocketChannel)key.channel();
             if(target!=self){
               ByteBuffer wrap = ByteBuffer.wrap(msg.getBytes());
                 target.read(wrap);
             }

        }


    }


    public static void main(String[] args) {
         GroupChatServer groupChatServer = new GroupChatServer();
        groupChatServer.listen();

    }


}
